import { EventEmitter } from "./event_emitter";
import { AppEvent } from "./app_event";

function ViewSettings(templateUrl: string, container: string) {
  return function (target: any) {
    // save a reference to the original constructor
    var original = target;

    // a utility function to generate instances of a class
    function construct(constructor: any, args: any) {
      var c: any = function () {
        return constructor.apply(this, args);
      }
      c.prototype = constructor.prototype;
      var instance = new c();
      instance._container = container;
      instance._templateUrl = templateUrl;
      return instance;
    }

    // the new constructor behaviour
    var f: any = function (...args) {
      return construct(original, args);
    }

    // copy prototype so intanceof operator still works
    f.prototype = original.prototype;

    // return new constructor (will override original)
    return f;
  }
}

class View extends EventEmitter implements IView {

  // the values of _container and _templateUrl must be set using the ViewSettings decorator
  protected _container: string;
  private _templateUrl: string;

  constructor(metiator: IMediator) {
    super(metiator);
  }

  // must be implemented by derived classes
  public initialize() {
    throw new Error('View.prototype.initialize() is abstract and must implemented.');
  }

  // must be implemented by derived classes
  public dispose() {
    throw new Error('View.prototype.dispose() is abstract and must implemented.');
  }

  // must be implemented by derived classes
  protected bindDomEvents(model: any) {
    throw new Error('View.prototype.bindDomEvents() is abstract and must implemented.');
  }

  // must be implemented by derived classes 后台框架无需绑定DOM事件
  // protected unbindDomEvents() {
  //   throw new Error('View.prototype.unbindDomEvents() is abstract and must implemented.');
  // }
}

export { View, ViewSettings };
